"""
地理分析API接口
提供地理分布、热力图、聚类分析等功能
"""
from fastapi import APIRouter, Depends, HTTPException, Query, Path
from sqlalchemy.orm import Session
from pydantic import BaseModel, Field
from typing import Dict, Any, List, Optional
from datetime import datetime

from core.database import get_db
from core.logging_config import get_logger, log_api_request
from core.auth import get_current_active_user, require_permission
from core.exceptions import ValidationError
from services.geo_analysis_service import geo_analysis_service

# 路由器
geo_analysis_router = APIRouter(tags=["地理分析"])

# 日志记录器
logger = get_logger("geo_analysis_api")


class GeoFilters(BaseModel):
    """地理分析过滤器"""
    start_date: Optional[datetime] = Field(None, description="开始日期")
    end_date: Optional[datetime] = Field(None, description="结束日期")
    province: Optional[str] = Field(None, description="省份过滤")
    city: Optional[str] = Field(None, description="城市过滤")
    district: Optional[str] = Field(None, description="区县过滤")
    pollution_type: Optional[str] = Field(None, description="污染类型过滤")
    processing_status: Optional[str] = Field(None, description="处理状态过滤")


@geo_analysis_router.get("/distribution")
@log_api_request("geo_distribution")
@require_permission("statistics:view")
async def get_geographic_distribution(
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取地理分布统计"""
    logger.info("获取地理分布统计请求")
    
    try:
        distribution = geo_analysis_service.get_geographic_distribution(db, result_id)
        
        return {
            "success": True,
            "data": distribution,
            "message": "地理分布统计获取成功"
        }
        
    except Exception as e:
        logger.error(f"获取地理分布统计失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@geo_analysis_router.get("/heatmap")
@log_api_request("geo_heatmap")
@require_permission("statistics:view")
async def get_heatmap_data(
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取热力图数据"""
    logger.info("获取热力图数据请求")
    
    try:
        heatmap_data = geo_analysis_service.get_heatmap_data(db, result_id)
        
        return {
            "success": True,
            "data": heatmap_data,
            "message": "热力图数据获取成功"
        }
        
    except Exception as e:
        logger.error(f"获取热力图数据失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@geo_analysis_router.get("/regional-comparison")
@log_api_request("geo_regional_comparison")
@require_permission("statistics:view")
async def get_regional_comparison(
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    regions: Optional[str] = Query(None, description="对比区域，逗号分隔"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取区域对比分析"""
    logger.info("获取区域对比分析请求")
    
    try:
        region_list = regions.split(",") if regions else None
        
        comparison = geo_analysis_service.get_regional_comparison(db, result_id, region_list)
        
        return {
            "success": True,
            "data": comparison,
            "message": "区域对比分析获取成功"
        }
        
    except Exception as e:
        logger.error(f"获取区域对比分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@geo_analysis_router.get("/clustering")
@log_api_request("geo_clustering")
@require_permission("statistics:view")
async def get_clustering_analysis(
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    radius: float = Query(0.01, ge=0.001, le=0.1, description="聚类半径（度）"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取聚类分析"""
    logger.info(f"获取聚类分析请求，半径: {radius}")
    
    try:
        clustering = geo_analysis_service.get_clustering_analysis(db, result_id, radius=radius)
        
        return {
            "success": True,
            "data": clustering,
            "message": "聚类分析获取成功"
        }
        
    except Exception as e:
        logger.error(f"获取聚类分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@geo_analysis_router.get("/density")
@log_api_request("geo_density")
@require_permission("statistics:view")
async def get_location_density_analysis(
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    grid_size: float = Query(0.01, ge=0.001, le=0.1, description="网格大小（度）"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取位置密度分析"""
    logger.info(f"获取位置密度分析请求，网格大小: {grid_size}")
    
    try:
        density = geo_analysis_service.get_location_density_analysis(db, result_id, grid_size)
        
        return {
            "success": True,
            "data": density,
            "message": "位置密度分析获取成功"
        }
        
    except Exception as e:
        logger.error(f"获取位置密度分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@geo_analysis_router.get("/dashboard")
@log_api_request("geo_dashboard")
@require_permission("statistics:view")
async def get_geo_dashboard(
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """获取地理分析仪表盘数据"""
    logger.info("获取地理分析仪表盘数据请求")
    
    try:
        # 并行获取各种地理分析数据
        import asyncio
        
        tasks = [
            asyncio.create_task(
                asyncio.to_thread(geo_analysis_service.get_geographic_distribution, db, result_id)
            ),
            asyncio.create_task(
                asyncio.to_thread(geo_analysis_service.get_heatmap_data, db, result_id)
            ),
            asyncio.create_task(
                asyncio.to_thread(geo_analysis_service.get_regional_comparison, db, result_id)
            ),
            asyncio.create_task(
                asyncio.to_thread(geo_analysis_service.get_clustering_analysis, db, result_id)
            )
        ]
        
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        # 处理结果
        distribution = results[0] if not isinstance(results[0], Exception) else {}
        heatmap = results[1] if not isinstance(results[1], Exception) else {}
        comparison = results[2] if not isinstance(results[2], Exception) else {}
        clustering = results[3] if not isinstance(results[3], Exception) else {}
        
        return {
            "geographic_distribution": distribution,
            "heatmap_data": heatmap,
            "regional_comparison": comparison,
            "clustering_analysis": clustering,
            "summary": {
                "total_locations": distribution.get("total_count", 0),
                "location_coverage": distribution.get("location_coverage", 0),
                "heatmap_points": heatmap.get("total_points", 0),
                "cluster_count": clustering.get("total_clusters", 0),
                "top_regions": comparison.get("regional_statistics", [])[:3]
            }
        }
        
    except Exception as e:
        logger.error(f"获取地理分析仪表盘数据失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@geo_analysis_router.get("/export/{format}")
@log_api_request("geo_export")
@require_permission("statistics:export")
async def export_geo_analysis(
    format: str = Path(..., description="导出格式：json, csv"),
    analysis_type: str = Query(..., description="分析类型：distribution, heatmap, clustering"),
    result_id: Optional[int] = Query(None, description="分析结果ID"),
    current_user=Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """导出地理分析数据"""
    logger.info(f"导出地理分析数据请求，格式: {format}, 类型: {analysis_type}")
    
    try:
        if analysis_type == "distribution":
            data = geo_analysis_service.get_geographic_distribution(db, result_id)
        elif analysis_type == "heatmap":
            data = geo_analysis_service.get_heatmap_data(db, result_id)
        elif analysis_type == "clustering":
            data = geo_analysis_service.get_clustering_analysis(db, result_id)
        else:
            raise HTTPException(status_code=400, detail="不支持的分析类型")
        
        if format == "json":
            return {
                "analysis_type": analysis_type,
                "data": data,
                "exported_at": datetime.now().isoformat()
            }
        elif format == "csv":
            # 这里可以实现CSV导出逻辑
            return {"message": "CSV导出功能待实现"}
        else:
            raise HTTPException(status_code=400, detail="不支持的导出格式")
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"导出地理分析数据失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))